package com.learn.security.theory.signature;

import com.learn.security.utils.asymmetric_encryption.RSAUtil;
import org.apache.commons.codec.binary.Hex;

import java.security.*;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.Map;

/**
 * RSA签名
 */
public class RSATest {

    public static final String encodeStr = "RSA security is security";

    public static void main(String[] args) {
        rasUtil();

        jdkRSA();

    }

    // 用RASUtil实现：RSA签名
    private static void rasUtil() {
        String publicKey;
        String privateKey;

        // 1.初始化发送方密钥
        Map<String, Object> keyMap = RSAUtil.initKey();
        publicKey = RSAUtil.getPublicKey(keyMap);
        privateKey = RSAUtil.getPrivateKey(keyMap);
        System.err.println("公钥: " + publicKey);
        System.err.println("私钥：" + privateKey);


        // 2.私钥产生签名
        System.out.println("私钥签名生成签名");
        String sign = RSAUtil.sign(encodeStr.getBytes(), privateKey);
        System.err.println("签名: " + sign);

        // 3.公钥验证签名
        System.out.println("公钥验证签名");
        Boolean status = RSAUtil.verify(encodeStr.getBytes(), publicKey, sign);
        System.err.println("状态: " + status);
    }

    /**
     * 用java实现rsa的签名及签名验证
     */
    private static void jdkRSA() {
        try {
            // 1.初始化密钥
            KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
            keyPairGenerator.initialize(1024);
            KeyPair keyPair = keyPairGenerator.generateKeyPair();
            RSAPublicKey rsaPublicKey = (RSAPublicKey) keyPair.getPublic();
            RSAPrivateKey rsaPrivateKey = (RSAPrivateKey) keyPair.getPrivate();

            // 2.进行签名
            PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(rsaPrivateKey.getEncoded());
            KeyFactory keyFactory = KeyFactory.getInstance("RSA");
            PrivateKey privateKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec);
            Signature signature = Signature.getInstance("MD5withRSA");
            signature.initSign(privateKey);
            signature.update(encodeStr.getBytes());
            byte[] result = signature.sign();
            // 这里是打印转为16进制的字符
            System.out.println("jdk rsa sign:" + Hex.encodeHexString(result));

            // 3.验证签名
            X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(rsaPublicKey.getEncoded());
            keyFactory = KeyFactory.getInstance("RSA");
            PublicKey publicKey = keyFactory.generatePublic(x509EncodedKeySpec);
            signature = Signature.getInstance("MD5withRSA");
            signature.initVerify(publicKey);
            signature.update(encodeStr.getBytes());
            boolean bool = signature.verify(result);
            System.out.println("jdk rsa verify:" + bool);
        } catch (Exception e) {
            System.out.println(e.toString());
        }

    }
}
